package com.softeem.tank;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * 游戏面板类，用于显示游戏画面和处理游戏逻辑。
 * 继承自JPanel，实现了ActionListener接口。
 */
public class GamePanel extends JPanel implements ActionListener {

    private Timer timer;
    private Tank tank;
    private ArrayList<Bullet> bullets;

    /**
     * 构造函数，初始化游戏面板。
     * 设置面板为可聚焦并监听键盘事件，初始化背景、双缓冲、坦克和子弹。
     * 启动定时器，用于更新游戏状态。
     */
    public GamePanel() {
        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);

        tank = new Tank();
        bullets = new ArrayList<>();
        // 初始化一个定时器，间隔时间为10毫秒，回调函数为当前类
        timer = new Timer(10, this);
    }

    /**
     * 开始游戏，启动定时器。
     */
    public void startGame() {
        timer.start();
    }

    /**
     * 重写paintComponent方法，用于绘制游戏画面。
     * 绘制坦克和所有可见的子弹，同步屏幕。
     * @param g 绘制用的Graphics对象。
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        g2d.drawImage(tank.getImage(), tank.getX(), tank.getY(), this);

        for (Bullet bullet : bullets) {
            if (bullet.isVisible()) {
                g2d.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
            }
        }

        Toolkit.getDefaultToolkit().sync();
    }

    /**
     * 处理动作事件，主要用于更新坦克和子弹的状态。
     * 调用坦克的移动方法和子弹的更新方法，然后重绘面板。
     *
     * @param e 动作事件对象。
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        tank.move();
        updateBullets();
        repaint();
    }

    /**
     * 更新子弹状态，移除不可见的子弹。
     */
    private void updateBullets() {
        ArrayList<Bullet> bulletsToRemove = new ArrayList<>();

        for (Bullet bullet : bullets) {
            if (bullet.isVisible()) {
                bullet.move();
            } else {
                bulletsToRemove.add(bullet);
            }
        }

        bullets.removeAll(bulletsToRemove);
    }

    /**
     * 键盘事件适配器，处理键盘的按下和释放事件。
     * 将键盘事件传递给坦克对象处理，按下空格键时发射子弹。
     */
    private class TAdapter extends KeyAdapter {
        /**
         * 当键盘按键事件发生时的处理方法。
         * 处理坦克的键盘控制和发射子弹逻辑。
         *
         * @param e 键盘事件对象。
         */
        @Override
        public void keyPressed(KeyEvent e) {
            tank.keyPressed(e);

            int key = e.getKeyCode();
            if (key == KeyEvent.VK_SPACE) {
                bullets.add(new Bullet(tank.getX() + 80, tank.getY()+5));
            }
        }

        /**
         * 当键盘释放事件发生时的处理方法。
         * 该方法重写了父类的keyReleased方法，以处理特定的键盘释放事件。
         * 它将键盘释放事件传递给坦克对象，让其处理相应的逻辑，如停止移动或射击等。
         *
         * @param e 键盘事件对象，包含了键盘释放的具体信息。
         */
        @Override
        public void keyReleased(KeyEvent e) {
            tank.keyReleased(e);
        }
    }
}
